import { defineStore } from 'pinia';
// 权限路由
import { homeRouters } from '@/api/public';
// 相关数据处理逻辑
import router from '@/router';
import { find, getTreeDataAtLevel } from '@/utils/tree';
import user from './user';

export default defineStore('guarder', {
	state: () => ({
		pageInfoError: '', // 512错误
		cachedComponents: [], // 缓存页面数据
		Menus: [], // 菜单数据
		homeMenus: [], // 首页第一层菜单
		addRouter: [], // 动态添加的路由
		RoutersList: [] // 所有的路由name数据
	}),
	actions: {
		// 生成路由
		GenerateRoutes() {
			return new Promise((resolve) => {
				// 向后端请求路由数据
				homeRouters().then((res) => {
					if (res?.data?.length) {
						const { Menus, Routes } = filterAsyncRouter(clone(res.data));

						this.homeMenus = getTreeDataAtLevel(Menus, 1);
						this.Menus = Menus;
						// 添加首页路由、404路由
						this.addRouter = [
							{
								path: '/',
								name: '/',
								redirect: find(Menus, true, (item) => !item.children).path,
								meta: {
									hideTabs: true
								}
							},
							...Routes,
							{
								path: '/:pathMatch(.*)',
								name: '/:pathMatch(.*)',
								redirect: '/404',
								meta: {
									hideTabs: true
								}
							}
						];
						this.addRouter.forEach((item) => {
							if (item.parentName) {
								router.addRoute(item.parentName, item);
							} else {
								router.addRoute(item);
							}
						});
						this.RoutersList = [...new Set(router.getRoutes().map((item) => item.name))];
						resolve();
					} else {
						ElMessageBox.alert('该角色用户暂无可视页面，请管理员分配角色权限！', '系统提示', {
							confirmButtonText: '确定',
							callback: () => {
								user().LogOut();
								window.location.reload();
							}
						});
					}
				});
			});
		}
	}
});

/*
 * 处理解决import动态加载组件 打包部署为空的问题
 * **为通配符,vite不支持require导入方式,故用import.meta.glob(vite动态导入)
 * import.meta.glob
 * 该方法匹配到的文件默认是懒加载，通过动态导入实现，构建时会分离独立的 chunk，是异步导入，返回的是 Promise
 * import.meta.globEager
 * 该方法是直接导入所有模块，并且是同步导入，返回结果直接通过 for...in循环就可以操作
 */
const modules = import.meta.glob('../views/**/*.vue');

// 遍历后台传来的路由字符串，转换为组件对象  动态添加路由
function filterAsyncRouter(data) {
	const RoutesData = Object.create(null),
		MenusData = Object.create(null);

	// 数据转换为对象
	data.forEach((item) => {
		/**
		 * id 数据ID
		 * parentId 父类ID
		 * component .vue文件路径
		 * layoutPath 布局路径 layoutPath == undefined为默认布局，layoutPath == 'ParentView'全屏布局，modules[`../views/${layoutPath}.vue`]自定义页面布局
		 * icon 菜单图标
		 * menuName 菜单名称
		 * menuType 菜单类型  M——目录、C——菜单
		 * path 菜单路由
		 * visible 是否显示
		 * isCache 是否缓存
		 * orderNum 排序
		 */
		const { id, parentId, layoutPath, icon, menuName, menuType, path, visible, isCache, orderNum } = item;
		let { component } = item;
		/**
		 * 目录
		 * component有值：则component为modules[`../views/${component}.vue`]，
		 */
		component = modules[`../views/${component}.vue`] || '';

		const meta = { title: menuName, icon, keepAlive: isCache == 1, hidden: visible == 1 },
			name = Object.values(RoutesData).find((routeData) => routeData.name === item.component) ? 'clonePath' : item.component || path;

		RoutesData[id] = {
			parentId,
			id,
			path,
			name,
			component,
			meta,
			orderNum
		};

		/**
		 * 目录
		 */
		if (menuType == 'M' && !component && parentId == '0') {
			RoutesData[id].parentName = '/Layout';
		}

		/**
		 * 无目录菜单
		 * 默认为 layoutPath 布局
		 * layoutPath == 'ParentView' 全屏布局
		 * modules[`../views/${layoutPath}.vue`]自定义页面布局
		 */
		if (parentId == '0' && menuType == 'C') {
			if (layoutPath == 'ParentView') return;

			const layout = modules[`../views/${layoutPath}.vue`];

			const parentName = !layoutPath ? '/Layout' : `/${layoutPath}`;

			// 添加布局页面
			if (!router.hasRoute(parentName)) {
				router.addRoute({
					name: parentName,
					path: parentName,
					component: layout
				});
			}

			RoutesData[id].parentName = parentName;
		}

		// 左边菜单数据
		if (visible !== 1) MenusData[id] = cloneDeep(RoutesData[id]);
	});

	// 树形结构数据
	function treeFn(data) {
		const handleData = [];
		for (const key in data) {
			const item = data[key];
			if (item.parentId == '0') {
				handleData.push(item);
				handleData.sort((a, b) => a.orderNum - b.orderNum);
			} else {
				const parent = data[item.parentId];
				if (parent) {
					if (!parent.children) parent.children = [];
					parent.children.push(item);
					parent.children.sort((a, b) => a.orderNum - b.orderNum);
				}
			}
		}
		return handleData;
	}

	// 菜单path拼接
	function pathFn(data, parentPath = '') {
		return data.map((item) => {
			item.path = `${parentPath}/${item.path}`;
			if (item.name === 'clonePath') item.name = item.path;
			if (item.children?.length) pathFn(item.children, item.path);
			return item;
		});
	}

	return {
		Menus: pathFn(treeFn(MenusData)),
		Routes: pathFn(treeFn(RoutesData))
	};
}
